package com.lzw.breezeNovel.WebAdmin.service.impl;


import com.lzw.breezeNovel.WebAdmin.mapper.AdminLoginMapper;
import com.lzw.breezeNovel.WebAdmin.service.AdminLoginService;
import com.lzw.breezeNovel.WebAdmin.vo.AdminLoginVo;
import com.lzw.breezeNovel.common.constant.RedisConstant;
import com.lzw.breezeNovel.common.exception.BaseException;
import com.lzw.breezeNovel.common.login.LoginUser;
import com.lzw.breezeNovel.common.login.LoginUserHolder;
import com.lzw.breezeNovel.common.result.ResultCodeEnum;
import com.lzw.breezeNovel.common.utils.JwtUtil;
import com.lzw.breezeNovel.common.utils.PasswordUtil;
import com.lzw.breezeNovel.model.entity.pojo.user.AdminLogin;
import com.lzw.breezeNovel.model.entity.query.PaginationResultQuery;
import com.lzw.breezeNovel.model.entity.query.SimplePage;
import com.lzw.breezeNovel.model.enums.user.AdminType;
import com.lzw.breezeNovel.model.enums.user.BaseStatus;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;



@Service
@SuppressWarnings("all")
public class AdminLoginServiceImpl  implements AdminLoginService {
    /**
     * 注入mapper
     */
    @Resource
    private AdminLoginMapper mapper;
    /**
     * 注入redis模板
     */
    @Resource
    private RedisTemplate redisTemplate;

    // 使用ThreadLocal确保日期格式化的线程安全
    private static final ThreadLocal<DateFormat> DATE_FORMATTER = ThreadLocal.withInitial(
            () -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    );




    /**
     * 注册
     * @param adminLogin
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(@NotNull AdminLogin adminLogin) {
        //根据用户手机号查询是否存在
        AdminLogin admin = mapper.selectByPhone(adminLogin.getPhone(),null);
        //判断是否存在
        if (admin != null) {
            throw new BaseException(ResultCodeEnum.ADMIN_ACCOUNT_EXIST_ERROR);
        }
        //获取密码
        String password = adminLogin.getPassword();
        //对密码进行加密
        password = PasswordUtil.encodePassword(password);
        //设置加密后的密码
        adminLogin.setPassword(password);
        //判断手机号是不是
        if(adminLogin.getPhone().equals("17707987108"))
        {
            adminLogin.setType(AdminType.ADMIN.getCode());
        }else
        {
            adminLogin.setType(AdminType.USER.getCode());
        }
        //设置用户的状态
        adminLogin.setStatus(BaseStatus.ENABLE.getCode());
        //设置默认的头像
        adminLogin.setAvatar("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
        //设置默认的邮箱
        adminLogin.setEmail("17707987108@163.com");
        //创建用户
        mapper.insert(adminLogin);

    }

    /**
     * 登录
     * @param adminLogin
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public String login(@NotNull AdminLogin adminLogin) {
        //根据用户名称获取用户消息
        AdminLogin admin = mapper.selectByUsername(adminLogin.getUsername(),null);
        //判断用户是否存在
        if (admin == null) {
            throw new BaseException(ResultCodeEnum.ADMIN_LOGIN_AUTH);
        }
        //获取用户的密码
        String password = adminLogin.getPassword();
        //对密码进行加密
        boolean matches = PasswordUtil.matches(password, admin.getPassword());
        //判断密码是否正确
        if (!matches) {
            throw new BaseException(ResultCodeEnum.ADMIN_LOGIN_PASSWORD_NOT_TRUE);
        }
        //获取用户的状态
        Integer status = admin.getStatus();
        //判断用户的状态
        if (status.equals(BaseStatus.DISABLE.getCode())) {
            throw new BaseException(ResultCodeEnum. ADMIN_ACCOUNT_DISABLED_ERROR);
        }
        //生成token
        String token = JwtUtil.createToken(admin.getPhone(), admin.getUsername());
        //将token存入redis
        redisTemplate.opsForValue().set(RedisConstant.ADMIN_LOGIN_PREFIX +
                admin.getPhone(), token, RedisConstant.APP_LOGIN_CODE_RESEND_TIME_SEC, TimeUnit.HOURS);
        return token;
    }

    @Override
    public void addLoginUser(@NotNull AdminLogin adminLogin) {
        //获取用户姓名
        String username = adminLogin.getUsername();
        //根据用户姓名获取用户信息
        AdminLogin admin = mapper.selectByUsername(username,null);
        //判断用户是否存在
        if (admin != null) {
            throw new BaseException(ResultCodeEnum.ADMIN_ACCOUNT_EXIST_ERROR);
        }
        //获取手机号
        String phone = adminLogin.getPhone();
        //根据手机号获取用户信息
        AdminLogin a = mapper.selectByPhone(phone,null);
        if (a != null) {
            throw new BaseException(ResultCodeEnum.ADMIN_ACCOUNT_EXIST_ERROR);
        }
        //获取邮箱
        String email = adminLogin.getEmail();
        //根据邮箱获取用户信息
        AdminLogin ad = mapper.selectByEmail(email,null);
        if (ad != null) {
            throw new BaseException(ResultCodeEnum.ADMIN_ACCOUNT_EXIST_ERROR);
        }
        //获取密码
        String password = adminLogin.getPassword();
        //对密码进行加密
        password = PasswordUtil.encodePassword(password);
        //设置加密后的密码
        adminLogin.setPassword(password);
        //设置用户的类型
        adminLogin.setType(AdminType.USER.getCode());
       mapper.insert(adminLogin);
    }

    /**
     * 分页查询用户信息
     * @param adminLoginVo
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public PaginationResultQuery<AdminLoginVo> queryLoginUser(@NotNull AdminLogin adminLoginVo) {
        //对分页数据进行优化
        Integer pageNum = Math.max(1,Optional.ofNullable(adminLoginVo.getPageNo()).orElse(1));
        Integer pageSize = Math.max(1,Optional.ofNullable(adminLoginVo.getPageSize()).orElse(10));
        //查询所有的数据
        Integer count = mapper.selectCount();
        //判断是否为空
        if(count == 0){
            return new PaginationResultQuery<>(0,pageSize,pageNum,0,new ArrayList<>());
        }
        //创建分页对象
        SimplePage simplePage = new SimplePage(count, pageSize, pageNum);
        //计算分页数据
        simplePage.action();
        adminLoginVo.setSimplePage(simplePage);
        //查询分页数据
        List<AdminLogin> adminLogins = mapper.selectByPage(adminLoginVo);
        //判断是否存在
        if(adminLogins == null || adminLogins.size() == 0){
            return new PaginationResultQuery<>(0,pageSize,pageNum,0,new ArrayList<>());
        }
        //创建集合
        List<AdminLoginVo> adminLoginVos = new ArrayList<>();
        //遍历集合
        for (AdminLogin adminLogin : adminLogins) {
            //创建vo对象
            AdminLoginVo adminLoginVo1 = new AdminLoginVo();
            //设置属性
            BeanUtils.copyProperties(adminLogin,adminLoginVo1);
            //获取用户的状态
            Integer status = adminLogin.getStatus();
            //判断用户的状态
            if (status.equals(BaseStatus.DISABLE.getCode())) {
                adminLoginVo1.setStatus(BaseStatus.DISABLE.getName());
            }else
            {
                adminLoginVo1.setStatus(BaseStatus.ENABLE.getName());
            }
            adminLoginVos.add(adminLoginVo1);
        }
        return new PaginationResultQuery<>(count,pageSize,pageNum,adminLogins.size(),adminLoginVos);
    }

    /**
     * 批量删除用户
     * @param ids
     */
    @Override
    public void deleteLoginUserBatch(Integer[] ids) {
        mapper.deleteBatch(ids);
    }

    /**
     * 修改用户信息
     * @param adminLogin
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateLoginUser(@NotNull AdminLogin adminLogin) {
        // 检查用户名、手机号、邮箱是否已存在
        checkAccountExistence(adminLogin);

        // 根据id获取用户信息
        AdminLogin existingAdmin = mapper.selectById(adminLogin.getId());

        // 清理未修改的字段
        clearUnchangedFields(existingAdmin, adminLogin);

        // 更新用户信息
        mapper.update(adminLogin);
    }

    /**
     * 检查用户名、手机号、邮箱是否已存在
     * @param adminLogin
     */
    @Transactional(readOnly = true)
    private void checkAccountExistence(@NotNull AdminLogin adminLogin) {
        checkFieldExistence(adminLogin.getUsername(), adminLogin.getId(), mapper::selectByUsername);
        checkFieldExistence(adminLogin.getPhone(), adminLogin.getId(), mapper::selectByPhone);
        checkFieldExistence(adminLogin.getEmail(), adminLogin.getId(), mapper::selectByEmail);
    }

    /**
     * 检查单个字段是否已存在
     * @param fieldValue 字段值
     * @param id 用户ID
     * @param selector 查询方法
     */
    private void checkFieldExistence(String fieldValue, Integer id, java.util.function.BiFunction<String, Integer, AdminLogin> selector) {
        if (fieldValue != null) {
            AdminLogin admin = selector.apply(fieldValue, id);
            if (admin != null) {
                throw new BaseException(ResultCodeEnum.ADMIN_ACCOUNT_EXIST_ERROR);
            }
        }
    }

    /**
     * 清理未修改的字段
     * @param existingAdmin 数据库中已存在的用户信息
     * @param adminLogin 待更新的用户信息
     */
    private void clearUnchangedFields(@NotNull AdminLogin existingAdmin, @NotNull AdminLogin adminLogin) {
        if (existingAdmin.getUsername().equals(adminLogin.getUsername())) {
            adminLogin.setUsername(null);
        }
        if (existingAdmin.getPhone().equals(adminLogin.getPhone())) {
            adminLogin.setPhone(null);
        }
        if (existingAdmin.getEmail().equals(adminLogin.getEmail())) {
            adminLogin.setEmail(null);
        }
    }



    /**
     * 获取当前登录用户信息
     * @return
     */
    @Override
    public AdminLoginVo getLoginUser() {
        //从当前线程后面获取用户手机号
        LoginUser loginUser = LoginUserHolder.getLoginUser();
        String phone = loginUser.getPhone();
        //根据手机号获取用户信息
        AdminLogin adminLogin = mapper.selectByPhone(phone,null);
        //创建vo对象
        AdminLoginVo adminLoginVo = new AdminLoginVo();
        //设置属性
        BeanUtils.copyProperties(adminLogin,adminLoginVo);
        return adminLoginVo;
    }

    /**
     * 修改当前登录用户信息
     * @param adminLogin
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCurrentLoginUser(@NotNull AdminLogin adminLogin) {
        //从当前线程后面获取用户手机号
        LoginUser loginUser = LoginUserHolder.getLoginUser();
        String phone = loginUser.getPhone();
        //根据手机号获取用户信息
        AdminLogin ad = mapper.selectByPhone(phone,null);
        //检查邮箱和手机号是否已存在
        checkAccountExistence(adminLogin);
        //清里未修改的字段
        clearUnchangedFields(ad,adminLogin);
        //判断密码是否为空
        if (adminLogin.getPassword() != null) {
            //加密密码
            String password = PasswordUtil.encodePassword(adminLogin.getPassword());
            adminLogin.setPassword(password);
        }
        mapper.update(adminLogin);
    }
}
